package com.ctshk.rpc.order.airexpress.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.rpc.airexpress.dto.AirportExpressInfoDTO;
import com.ctshk.rpc.airexpress.service.IAirportExpressService;
import com.ctshk.rpc.finance.req.bill.BillAddRefundReq;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.order.airexpress.constants.AirportExpressConstants;
import com.ctshk.rpc.order.airexpress.entity.AirportExpressOrder;
import com.ctshk.rpc.order.airexpress.entity.AirportExpressOrderRefund;
import com.ctshk.rpc.order.airexpress.mapper.AirportExpressOrderMapper;
import com.ctshk.rpc.order.airexpress.mapper.AirportExpressOrderRefundMapper;
import com.ctshk.rpc.order.airexpress.req.AirportExpressOrderRefundApprovalRecordReq;
import com.ctshk.rpc.order.airexpress.req.AirportExpressOrderRefundApprovalReq;
import com.ctshk.rpc.order.airexpress.service.IAirportExpressOrderRefundService;
import com.ctshk.rpc.system.dto.MainDataCurrencyListDTO;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.req.crm.member.CrmMemberUpdatePointsReq;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 机场快线退款记录 服务实现类
 * </p>
 *
 * @author 叶冠峰
 * @since 2021-02-23
 */
@DubboService
@Slf4j
public class AirportExpressOrderRefundServiceImpl extends ServiceImpl<AirportExpressOrderRefundMapper, AirportExpressOrderRefund> implements IAirportExpressOrderRefundService {
    @Autowired
    AirportExpressOrderMapper airportExpressOrderMapper;
    @Autowired
    AirportExpressOrderRefundMapper airportExpressOrderRefundMapper;
    @DubboReference
    IAirportExpressService airportExpressService;
    @DubboReference
    ISysApprovalService sysApprovalService;
    @DubboReference
    ISysUserService sysUserService;
    @DubboReference
    IFinanceBillService financeBillService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int delete(Long id, Long userId) {
        AirportExpressOrderRefund airportExpressOrderRefund = airportExpressOrderRefundMapper.selectById(id);
        if (!ApprovalStatus.REVIEW_NO.getCode().equals(airportExpressOrderRefund.getStatus())) {
            // 审批失败状态的退款记录才可以删除
            throw new BusinessException(SystemError.AIREXPRESS_ORDER_60002);
        }
        airportExpressOrderRefund.setModifiedId(userId);
        airportExpressOrderRefund.setGmtModified(LocalDateTime.now());
        airportExpressOrderRefund.setIsDeleted(IsDeletedCode.YES.getCode());
        int num = airportExpressOrderRefundMapper.updateById(airportExpressOrderRefund);
        return num;
    }

    @Override
    public Result approval(AirportExpressOrderRefundApprovalReq req) {
        if (req.getApprovalId() == null) {
            return Result.failed(SystemError.SYS_402);
        }
        if (!ApprovalStatus.isCheckStatus(req.getApprovalStatus())) {
            return Result.failed(SystemError.SYS_402);
        }
        QueryWrapper<AirportExpressOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.lambda().eq(AirportExpressOrder::getId, req.getBusinessId());
        orderQueryWrapper.lambda().eq(AirportExpressOrder::getIsDeleted, IsDeletedCode.NO.getCode());
        AirportExpressOrder airportExpressOrder = airportExpressOrderMapper.selectOne(orderQueryWrapper);
        if (airportExpressOrder == null) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60002);
        }
        if (!ApprovalStatus.REVIEWING.getCode().equals(airportExpressOrder.getCancelStatus())) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60027);
        }
        QueryWrapper<AirportExpressOrderRefund> orderRefundQueryWrapper = new QueryWrapper<>();
        orderRefundQueryWrapper.lambda().eq(AirportExpressOrderRefund::getOrderId, req.getBusinessId());
        orderRefundQueryWrapper.lambda().eq(AirportExpressOrderRefund::getIsDeleted, IsDeletedCode.NO.getCode());
        List<AirportExpressOrderRefund> airportExpressOrderRefundList = airportExpressOrderRefundMapper.selectList(orderRefundQueryWrapper);
        if (CollectionUtils.isEmpty(airportExpressOrderRefundList)) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60028);
        }
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        log.info("【机场快线订单-退款】approval status:{}", req.getApprovalStatus());
        if (ApprovalStatus.REVIEW_YES.getCode() == req.getApprovalStatus()) {
            if (CollectionUtils.isEmpty(req.getOrderRefundApprovalRecordReqList())) {
                throw new BusinessException(SystemError.AIREXPRESS_ORDER_60036);
            }
            // 审批通过
            airportExpressOrder.setCancelStatus(ApprovalStatus.REVIEW_YES.getCode());
            // 校验审批金额
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (AirportExpressOrderRefund refund : airportExpressOrderRefundList) {
                refund.setStatus(ApprovalStatus.REVIEW_YES.getCode());
                for (AirportExpressOrderRefundApprovalRecordReq orderRefundApprovalRecordReq : req.getOrderRefundApprovalRecordReqList()) {
                    if (Objects.equals(orderRefundApprovalRecordReq.getId(), refund.getId())) {
                        BigDecimal approvalAmount = orderRefundApprovalRecordReq.getApprovalAmount();
                        totalAmount = totalAmount.add(approvalAmount.multiply(refund.getExchangeRate()));
                        refund.setApprovalAmount(orderRefundApprovalRecordReq.getApprovalAmount());
                        break;
                    }
                }
            }
            BigDecimal cancellationCharge = airportExpressService.getCancellationChargeById(airportExpressOrder.getAirportExpressId(), airportExpressOrder.getReceivableAmount());
            BigDecimal refundAmount = airportExpressOrder.getReceivableAmount().subtract(cancellationCharge);
            if (totalAmount.compareTo(refundAmount) > 0) {
                throw new BusinessException(SystemError.AIREXPRESS_ORDER_60035);
            }
            /**
             * 新增财务退款记录
             */
            log.info("【机场快线订单】生成供应商预订，查询机场快线信息, id:{}", airportExpressOrder.getAirportExpressId());
            AirportExpressInfoDTO airportExpressInfoDTO = airportExpressService.selectInfo(airportExpressOrder.getAirportExpressId());
            log.info("【机场快线订单】生成供应商预订，查询机场快线信息, info:{}", JSON.toJSONString(airportExpressInfoDTO));
            UserDTO userSaleDTO = sysUserService.queryCacheUser(airportExpressOrder.getSalesmanId());
            List<BillAddRefundReq> billAddRefundReqs = new ArrayList<>();
            /**
             * 更新会员积分
             */
            updateMember(airportExpressOrder);
            for (AirportExpressOrderRefund orderRefund : airportExpressOrderRefundList) {
                BillAddRefundReq billAddRefundReq = new BillAddRefundReq();
                billAddRefundReqs.add(billAddRefundReq);
                billAddRefundReq.setBillNumber(orderRefund.getRefundNumber());
                billAddRefundReq.setBusinessType(SystemBusinessType.AIR_EXPRESS.getCode());
                billAddRefundReq.setCollectionAmount(orderRefund.getRefundAmount());
                billAddRefundReq.setCurrencyId(orderRefund.getCurrencyId());
                billAddRefundReq.setCurrencyName(orderRefund.getCurrency());
                billAddRefundReq.setExchangeRate(orderRefund.getExchangeRate().doubleValue());
                billAddRefundReq.setRefundTime(orderRefund.getGmtCreate());
                billAddRefundReq.setSaleOrderNumber(airportExpressOrder.getOrderNumber());
                billAddRefundReq.setSaleOrderId(airportExpressOrder.getId());
                billAddRefundReq.setProductId(Arrays.asList(airportExpressOrder.getAirportExpressId()));
                billAddRefundReq.setProductName(airportExpressInfoDTO.getTicketTypeNameCn());
                billAddRefundReq.setProductNumber(airportExpressInfoDTO.getProductCode());
                billAddRefundReq.setResourceInfo(Arrays.asList(airportExpressInfoDTO.getTicketTypeNameCn()));
                billAddRefundReq.setSaleUserId(userSaleDTO.getId());
                billAddRefundReq.setSaleUserName(userSaleDTO.getFullName());
                billAddRefundReq.setSaleDeptId(userSaleDTO.getDeptId());
                billAddRefundReq.setUserId(req.getUserId());
            }
            log.info("【机场快线订单退款】新增财务退款记录，req:{}", JSON.toJSONString(billAddRefundReqs));
            financeBillService.addRefund(billAddRefundReqs);
        } else if (ApprovalStatus.REVIEW_NO.getCode() == req.getApprovalStatus()) {
            //审批不通过
            airportExpressOrder.setCancelStatus(ApprovalStatus.REVIEW_NO.getCode());
            for (AirportExpressOrderRefund airportExpressOrderRefund : airportExpressOrderRefundList) {
                airportExpressOrderRefund.setStatus(ApprovalStatus.REVIEW_NO.getCode());
            }
        } else {
            //撤回
            airportExpressOrder.setCancelStatus(null);
            for (AirportExpressOrderRefund airportExpressOrderRefund : airportExpressOrderRefundList) {
                airportExpressOrderRefund.setStatus(null);
                airportExpressOrderRefund.setIsDeleted(IsDeletedCode.YES.getCode());
            }
        }
        /**
         * 审批
         */
        Result<ApprovalCheckDTO> result = sysApprovalService.check(req.getApprovalId(), req.getUserId(),
                req.getApprovalStatus(), req.getComments());
        if (!result.isSuccess()) {
            SystemError systemError = SystemError.getDefined(result.getCode());
            return Result.failed(systemError);
        }
        if (result.getData() == null || !result.getData().getIsFinish()) {
            return Result.success();
        }
        for (AirportExpressOrderRefund airportExpressOrderRefund : airportExpressOrderRefundList) {
            airportExpressOrderRefund.setModifiedId(req.getUserId());
            airportExpressOrderRefund.setGmtModified(nowLocalDateTime);
            airportExpressOrderRefundMapper.updateById(airportExpressOrderRefund);
        }
        airportExpressOrder.setModifiedId(req.getUserId());
        airportExpressOrder.setGmtModified(nowLocalDateTime);
        airportExpressOrderMapper.updateById(airportExpressOrder);
        return Result.success();
    }

    private void updateMember(AirportExpressOrder airportExpressOrder) {
        /**
         * do something 退积分，退优惠码(机场快线无优惠码)，退银联优惠
         */
        if (airportExpressOrder.getIfMember() == AirportExpressConstants.IF_MEMBER_YES) {
            /*MainDataCurrencyListDTO mainDataCurrencyListDTO = getExchangeRateByName(Currency.CNY.getCurrency());
            BigDecimal crmExchangeRateCNY = mainDataCurrencyListDTO.getCrmExchangeRate();
            try {
                // 构建创建用户ID，人民币金额，回退积分点数
                String crmUserId = String.valueOf(currentUser.getId()).substring(0, 12);
                BigDecimal rmbAmount = airportExpressOrder.getReceivableAmount().divide(crmExchangeRateCNY, 2, BigDecimal.ROUND_HALF_UP);

                CrmMemberUpdatePointsReq crmMemberUpdatePointsReq = new CrmMemberUpdatePointsReq();
                crmMemberUpdatePointsReq.setUpdateType(2);
                crmMemberUpdatePointsReq.setNumPoints(new BigDecimal(airportExpressOrder.getUsingPoints()));//do积分点数
                crmMemberUpdatePointsReq.setXCtsProdDesc("單項委託-火车巴士船票(机场快线)");//do板塊產品描述 (建議使用: 集團產品名稱 + “ – “ + 板塊產品名稱, 例如: 港澳参团游 - 主题游)")
                crmMemberUpdatePointsReq.setTxnNum(airportExpressOrder.getOrderNumber() + "-3");//do交易編號 (如為旅行團交易, 目前我們的格式是 旅行團交易編號 + ‘-‘ + 序號, 例如: 01P08192131025A155506-1
                crmMemberUpdatePointsReq.setAmtVal(airportExpressOrder.getReceivableAmount());
                crmMemberUpdatePointsReq.setXCtsRmbAmount(rmbAmount);
                crmMemberUpdatePointsReq.setCreateUserid(crmUserId);
                crmMemberUpdatePointsReq.setXCtsTxnOrgCode("219910000010");
                crmMemberUpdatePointsReq.setTxnChannelCd("16");
                crmMemberUpdatePointsReq.setXCtsTxnChnNum("211099000010");
                crmMemberUpdatePointsReq.setProdName("8821090000");
                crmMemberUpdatePointsReq.setXCtsProdCode("8821090300");
                crmMemberService.updatePoints(crmMemberUpdatePointsReq);
            } catch (Exception e) {
                if (e instanceof BusinessException) {
                    throw e;
                } else {
                    throw new BusinessException(SystemError.AIREXPRESS_ORDER_60009);
                }
            }*/
        } else {
            /**
             * 扣减银联优惠,机场快线无银联优惠、推广码功能
             */
            /*QueryWrapper<AirportExpressOrderCollection> collectionQueryWrapper = new QueryWrapper<>();
            collectionQueryWrapper.lambda().eq(AirportExpressOrderCollection::getOrderId, airportExpressOrder.getId());
            collectionQueryWrapper.lambda().eq(AirportExpressOrderCollection::getIsDeleted, IsDeletedCode.NO);
            List<AirportExpressOrderCollection> airportExpressOrderCollectionList = airportExpressOrderCollectionMapper.selectList(collectionQueryWrapper);
            if (CollectionUtils.isNotEmpty(airportExpressOrderCollectionList)) {
                AirportExpressOrderCollection airportExpressOrderCollectionBank = null;
                String payer = null;
                for (AirportExpressOrderCollection airportExpressOrderCollection : airportExpressOrderCollectionList) {
                    if (airportExpressOrderCollection.getCollectionWayId() == OrderAirexpressConstants.PAY_REFUND_METHOD_IYL) {//1372458875539845121 銀行優惠
                        airportExpressOrderCollectionBank = airportExpressOrderCollection;
                    }
                    if (airportExpressOrderCollection.getCollectionWayId() == OrderAirexpressConstants.PAY_REFUND_METHOD_CR || airportExpressOrderCollection.getCollectionWayId() == OrderAirexpressConstants.PAY_REFUND_METHOD_CUP) {//信用卡,银行卡
                        payer = airportExpressOrderCollection.getPayer();
                    }
                }
                if (airportExpressOrderCollectionBank != null) {
                    OperateBankRefundReq deductReq = new OperateBankRefundReq();
                    deductReq.setId(airportExpressOrderCollectionBank.getUnionpayDiscountId());//银联优惠ID
                    deductReq.setRefundTotalPaidIn(airportExpressOrderCollectionBank.getStandardAmount());//本位币金额
                    deductReq.setCardNumber(payer);//卡号
                    deductReq.setBusinessType(SystemBusinessType.AIR_EXPRESS.getCode());
                    deductReq.setRelationId(airportExpressOrder.getAirportExpressId());//订单ID
                    deductReq.setChannelId(OrderSource.CPM.getCode().longValue());//订单来源
                    Result deductResult = operateBankPreferenceService.refundUpdate(deductReq, currentUser);
                    if (!deductResult.isSuccess()) {
                        // 校验银行优惠不满足条件
                        SystemError defined = SystemError.getDefined(deductResult.getCode());
                        throw new BusinessException(defined);
                    }
                }
            }*/
        }
    }

    @Override
    public Result confirmRefund(String refundNumber, Long userId) {
        AirportExpressOrderRefund airportExpressOrderRefund = airportExpressOrderRefundMapper.selectOne(Wrappers.<AirportExpressOrderRefund>lambdaQuery()
                .eq(AirportExpressOrderRefund::getRefundNumber, refundNumber));
        if (airportExpressOrderRefund == null) {
            //收款记录不存在
            return Result.failed(SystemError.AIREXPRESS_ORDER_60028);
        }
        airportExpressOrderRefund.setStatus(ApprovalStatus.REFUND_SUCCESS.getCode());
        airportExpressOrderRefund.setModifiedId(userId);
        airportExpressOrderRefund.setGmtModified(LocalDateTime.now());
        airportExpressOrderRefundMapper.updateById(airportExpressOrderRefund);
        return Result.success();
    }
}
